package com.example.fang.demodruid.concurency3;

import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;

public class MyTest3 {

    public static void main(String args[]){
        BoundedContainer boundedContainer=new BoundedContainer();
        //lamba表达式 创建10个线程
        IntStream.range(0,20).forEach(i->new Thread(()->{
            try {
               boundedContainer.put("hello");
            }catch (Exception e){
                e.printStackTrace();
            }
        }).start());

        IntStream.range(0,20).forEach(i->new Thread(()->{
            try {
                boundedContainer.take();
            }catch (Exception e){
                e.printStackTrace();
            }
        }).start());


    }

};


class BoundedContainer{
     private String[] elements=new String[10];

     private Lock lock=new ReentrantLock();

     private Condition notEmptyConfition=lock.newCondition();

     private Condition notFullConfition=lock.newCondition();

     private int elementCount;//elements数组中已有的元素数量

     private int putIndex;

     private int takeIndex;

     public void put(String element){
         this.lock.lock();//获取到线程的锁
         try {
           while (this.elementCount==this.elements.length){
               notEmptyConfition.await();//释放当前锁
           }
           elements[putIndex]=element;
           if(++putIndex==this.elements.length){
               putIndex=0;
           }
           ++elementCount;
           System.out.println("put method:"+ Arrays.toString(elements));
           notEmptyConfition.signal();
         }catch (Exception e){
             e.printStackTrace();
         }finally {
             lock.unlock();
         }
     }


     public String take() throws InterruptedException {
         this.lock.lock();
        try {
           while (0==this.elementCount){
              notEmptyConfition.await();
           };
           String element=elements[takeIndex];
           elements[takeIndex]=null;
           if(++takeIndex==this.elements.length){
              takeIndex=0;
           }
           --elementCount;
           System.out.println("take method:"+Arrays.toString(elements));
           return  element;
        }finally {
            lock.unlock();
        }

     };




}
